/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package commons.util;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;

import org.openide.util.NbBundle;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author Susanta Tewari
 * @since Aug 20, 2011
 */
public class BinaryDataUtil {

    /**
     * @param labels sample element label
     * @param labelSeq sequence ('0' and '1' characters with no space) for each label
     * @return
     */
    public static byte[][] getBinaryData(List<String> labels, Map<String, String> labelSeq) {

        byte[][] s = new byte[labels.size()][];

        for (int i = 0; i < s.length; i++) {

            String allele     = labelSeq.get(labels.get(i));

            char[] char_array = allele.toCharArray();

            byte[] temp       = new byte[char_array.length];

            for (int j = 0; j < char_array.length; j++) {

                temp[j] = Byte.parseByte("" + char_array[j]);
            }

            s[i] = temp;

        }

        return s;

    }


    /**
     * Parses binary string into a byte array.
     *
     * @param binaryString binary string containing characters '0' and/or '1'
     * @return byte array containing binary values
     */
    public static byte[] parseBinaryString(String binaryString) {

        if (binaryString == null) {
            ExceptionUtil.throwIllegalArgExNull("binaryString");
        }

        char[] char_array = binaryString.toCharArray();

        byte[] result     = new byte[char_array.length];

        for (int j = 0; j < char_array.length; j++) {

            if ((char_array[j] != '0') && (char_array[j] != '1')) {

                final String msg = NbBundle.getMessage(BinaryDataUtil.class,
                                       "Invaild_Binary_String", binaryString);

                throw new IllegalArgumentException(msg);
            }

            result[j] = Byte.parseByte("" + char_array[j]);
        }

        return result;
    }


    /**
     * Method description
     *
     *
     * @param val
     *
     * @return
     */
    public static String buildBinaryString(byte[] val) {

        StringBuilder stringBuilder = new StringBuilder(val.length);

        for (int i = 0; i < val.length; i++) {

            stringBuilder.append(val[i]);
        }

        return stringBuilder.toString();
    }


    /**
     * A utility method that transforms data for phylogeny algorithms from a user friendly format to
     * that of the algorithm.
     *
     * @param data a user friendly format of data for phylogeny algorithms
     * @return data format used by the phylogeny algorithms
     */
    public static Collection<byte[]> transformData(final Collection<String> data) {

        Function<String, byte[]> function = new Function<String, byte[]>() {

            @Override
            public byte[] apply(String f) {

                return parseBinaryString(f);
            }
        };

        return Collections2.transform(data, function);

    }
}
